﻿using System;
using System.IO;
using System.Threading;
using System.Windows;
using System.Windows.Threading;
using FileClient.Wpf.Ws;
using FileEfCore.DbContexts;
using Hardcodet.Wpf.TaskbarNotification;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using NLog;
using NLog.Extensions.Logging;

namespace FileClient.Wpf
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        private IClientWsListener _clientWsListener;
        private readonly MainWindow _mainWindow;
        private static Mutex mutex;
        public static TaskbarIcon TaskbarIcon;
        public static ServiceProvider ServiceProvider { get; set; }

        public App()
        {
            this.Startup += App_Startup;
            _mainWindow = new MainWindow();
        }

        private void App_Startup(object sender, StartupEventArgs e)
        {
            var appName = ResourceAssembly.GetName().Name;
            mutex = new Mutex(true, appName, out bool ret);
            if (!ret)
            {
                MessageBox.Show("程序已经打开");
                Environment.Exit(0);
            }
        }

        protected override void OnStartup(StartupEventArgs e)
        {
            try
            {
                var configuration = CreateConfiguration();
                var service = new ServiceCollection();
                ConfigurationService(service, configuration);
                ServiceProvider = service.BuildServiceProvider();
                Core.App.ServiceProvider = ServiceProvider;
                base.OnStartup(e);
                SetNlogConfig();
                StartWsListener();
                InitializeDb();
                ShowStartWindows();
                TaskbarIcon = (TaskbarIcon)FindResource("Taskbar");
                DispatcherUnhandledException += OnDispatcherUnhandledException;
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message, "警告", MessageBoxButton.OKCancel);
               // throw;
            }
        }

        private void ShowStartWindows()
        {
            Current.MainWindow = _mainWindow;
            _mainWindow.Show();
        }

        private IConfiguration CreateConfiguration()
        {
            var homeDir = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
            var appSettingConfig = Path.Combine(homeDir, ".ums-file-client/appsetting.json");
            CreateUmsDirectoryIfNotExist(Path.GetDirectoryName(appSettingConfig));
            if (!File.Exists(Path.Combine(homeDir, appSettingConfig)))
            {
                var configPopupWindow = new ConfigPopupWindow(appSettingConfig);
                configPopupWindow.ShowDialog();
                if (!configPopupWindow.IsSetting)
                {
                    throw new Exception("请先对文件服务进行配置");
                }
            }

            var builder = new ConfigurationBuilder()
                    .AddJsonFile(appSettingConfig, false, true)
                ;
            var configuration = builder.Build();
            return configuration;
        }


        private void CreateUmsDirectoryIfNotExist(string directoryName)
        {
            if (!Directory.Exists(directoryName))
            {
                Directory.CreateDirectory(directoryName);
            }
        }

        private void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
        {
            e.Handled = true;
            var logger = ServiceProvider.GetService<ILogger<App>>();
            logger?.LogError("应用程序发送未被捕获的异常,异常消息:{0}", e.Exception.Message, e);
        }

        private void StartWsListener()
        {
            _clientWsListener = ServiceProvider.GetRequiredService<IClientWsListener>();
            var logger = ServiceProvider.GetRequiredService<ILogger<App>>();
            _clientWsListener.Listen();
            logger.LogInformation($"Ws服务启动成功,监听端口为:{_clientWsListener.Port}");
        }

        private void SetNlogConfig()
        {
            var logConfigPath = Path.Combine(Directory.GetCurrentDirectory(), "NLog.config");
            LogManager.LoadConfiguration(logConfigPath);
            var loggerFactory = ServiceProvider.GetRequiredService<ILoggerFactory>();
            loggerFactory.AddNLog();
        }

        private void ConfigurationService(ServiceCollection services, IConfiguration configuration)
        {
            services.AddSingleton<IClientWsListener, ClientWsListener>();
            services.AddLogging();

            services.AddSingleton(configuration);
            services.AddFileClientServices(configuration,".ums-file-client/fileinfo.db");
        }

        private void InitializeDb()
        {
            using var scope = ServiceProvider.CreateScope();
            using var context = scope.ServiceProvider.GetRequiredService<FileDbContext>();
            context.Database.EnsureCreated();
        }

        protected override void OnExit(ExitEventArgs e)
        {
            base.OnExit(e);
            _clientWsListener?.Dispose();
        }
    }
}